<?php
/*
 * model 的通用方法
 * model 需要有属性值 $table
 * 非内部业务不准使用这些方法，对外业务一定要prepare绑定占位符
 *
 */
trait Lib_BaseTraits
{
    public function getItemById($id, $cache = false, $pk = 'id')
    {
        if (!$id) {
            return array();
        }
        $sql = "SELECT * FROM {$this->table} WHERE {$pk}=:id";
        $data = array(':id' => $id);
        $cache ? $this->dao->conn()->setTag(self::$tag)->setKey('id_'.$id) : $this->dao->conn(false)->noCache();
        $res = $this->dao->preparedSql($sql, $data)->fetchOne();

        return $res;
    }

    public function deleteItemById($id, $pk = 'id')
    {
        if (!$id) {
            return 0;
        }
        $sql = "DELETE FROM {$this->table} WHERE {$pk}=:id";
        $data = array(':id' => intval($id));
        $res = $this->dao->conn(false)->noCache()->preparedSql($sql, $data)->affectedCount();
        $this->dao->clearTag(self::$tag);

        return $res;
    }

    public function getOne($fields = array(), $where = array(), $cache = false)
    {
        $fields = empty($fields) ? '*' : implode(',', $fields);
        $where_str = '';
        if (!empty($where)) {
            $where_str = 'WHERE '.implode(' AND ', $where);
        }
        $sql = "SELECT {$fields} FROM {$this->table} {$where_str} LIMIT 1";

        $cache ? $this->dao->conn()->setTag(self::$tag) : $this->dao->conn(false)->noCache();
        $res = $this->dao->preparedSql($sql, array())->fetchOne();

        return $res;
    }

    public function getAll($fields = array(), $cache = false)
    {
        $fields = empty($fields) ? '*' : implode(',', $fields);
        $sql = "SELECT {$fields} FROM {$this->table}";
        $cache ? $this->dao->conn()->setTag(self::$tag) : $this->dao->conn(false)->noCache();
        $res = $this->dao->preparedSql($sql, array())->fetchAll();

        return $res;
    }

    public function singleUpdate($saveData, $pk = 'id')
    {
        $id = $saveData[$pk];
        unset($saveData[$pk]);
        $arr = $data = array();
        $data[':id'] = $id;
        foreach ($saveData as $key => $value) {
            $temp = ':'.$key;
            $arr[] = '`'.$key.'`='.$temp;
            $data[$temp] = $value;
        }
        $sql = 'UPDATE `'.$this->table.'` SET '.implode(',', $arr).' WHERE '.$pk.'=:id';
        $res = $this->dao->conn(false)->noCache()->preparedSql($sql, $data)->affectedCount();
        $this->dao->clearTag(self::$tag);
        return $res;
    }

    public function singleInsert($saveData, $auto_increase = true, $pk = 'id')
    {
        $arrFields = $arrValues = $data = array();
        foreach ($saveData as $key => $value) {
            $arrFields[] = '`'.$key.'`';
            $temp = ':'.$key;
            $data[$temp] = $value;
            $arrValues[] = $temp;
        }
        $sql = 'INSERT INTO `'.$this->table.'` ('.implode(',', $arrFields).') VALUES ('.implode(',', $arrValues).')';

        if ($auto_increase) {
            $res = $this->dao->conn(false)->noCache()->preparedSql($sql, $data)->lastInsertId();
            $this->dao->clearTag(self::$tag);
            return $res;
        } else {
            $res = $this->dao->conn(false)->noCache()->preparedSql($sql, $data)->affectedCount();
            $this->dao->clearTag(self::$tag);
            return $res ? $saveData[$pk] : false;
        }
    }

    function getAllBySearch($fields = array(),$search = array(),$cache = false,$count=false){
        $fields = empty($fields) ? '*' : implode(',',$fields);
        if($count){
            $fields = ' count(*) as total ';
        }
        $search_str = '';
        if(isset($search['where']) && !empty($search['where'])){
            $search_str .= 'WHERE '.implode(' AND ',$search['where']);
        }
        if(isset($search['group']) && $search['group']){
            $search_str .= ' GROUP BY '.$search['group'];
            if(isset($search['having']) && $search['having']){
                $search_str .= ' HAVING '.$search['having'];
            }
        }
        if(isset($search['order']) && $search['order']){
            $search_str .= ' ORDER BY '.$search['order'];
        }
        if(!$count && isset($search['limit']) && $search['limit']){
            $search['start'] = isset($search['start']) ? $search['start'] : 0;
            $search_str .= ' LIMIT '.$search['start'].','.$search['limit'];
        }

        $join = empty($search['join']) ? '' : $search['join'];
        $sql = "SELECT {$fields} FROM {$this->table} {$join} {$search_str}";
        $cache ? $this->dao->conn()->setTag(self::$tag) : $this->dao->conn(false)->noCache();
        $res = $this->dao->preparedSql($sql, array())->fetchAll();
        return $res;
    }

    function getGroupTotalBySearch($fields = array(),$search = array(),$cache = false){
        $fields = empty($fields) ? '*' : implode(',',$fields);
        $search_str = '';
        if(isset($search['where']) && !empty($search['where'])){
            $search_str .= 'WHERE '.implode(' AND ',$search['where']);
        }
        if(isset($search['group']) && $search['group']){
            $search_str .= ' GROUP BY '.$search['group'];
            if(isset($search['having']) && $search['having']){
                $search_str .= ' HAVING '.$search['having'];
            }
        }
        $sql = "SELECT count(*) as num from (SELECT {$fields} FROM {$this->table} {$search_str}) as t ";
        $cache ? $this->dao->conn()->setTag(self::$tag) : $this->dao->conn(false)->noCache();
        $res = $this->dao->preparedSql($sql, array())->fetchAll();
        return $res;
    }

    /**
     * 开启事务
     * @param unknown $id
     */
    function beginTransaction(){
        return $this->dao->conn(false)->beginTransaction();;
    }


    /**
     * 回滚
     * @param unknown $id
     */
    function rollback(){
        return $this->dao->rollback();
    }


    /**
     * 提交事务
     * @param unknown $id
     */
    function commit(){
        $res =  $this->dao->commit();
        if(!$res){
            $this->dao->rollback();
            return false;
        }
        return true;
    }
}
